package com.ymatou.iapi.optrade.testcase;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.google.common.collect.Lists;
import com.ymatou.iapi.optrade.parameter.enums.AuthenticateFeeTypeEnum;
import com.ymatou.iapi.optrade.parameter.enums.AuthenticateFreightTypeEnum;
import com.ymatou.iapi.optrade.parameter.enums.LogisticsTypeEnum;
import com.ymatou.iapi.optrade.parameter.req.ApplyRefundReq;
import com.ymatou.iapi.optrade.parameter.req.PlaceOrderReq;
import com.ymatou.iapi.optrade.parameter.utill.Utils;
import com.ymatou.iapi.optrade.parameter.vo.OrderGroupVo;
import com.ymatou.iapi.optrade.parameter.vo.OrderItemVo;
import com.ymatou.iapi.optrade.parameter.vo.OrderVo;
import com.ymatou.iapi.optrade.parameter.vo.SalesRefundInfoVo;
import com.ymatou.iapi.optrade.resp.Order;
import com.ymatou.iapi.optrade.resp.TradingServiceResp;
import com.ymatou.iapi.optrade.service.ApplySalesRefundCall;
import com.ymatou.iapi.optrade.service.RefundService;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymttest.business.service.YMTTrading.TradingCallService;
import com.ymttest.business.service.YMTTrading.TradingPlaceAuthenticateCallService;
import com.ymttest.business.service.YMTTrading.TradingPlaceOrderCallService;
import com.ymttest.business.service.YMTTrading.TradingProductVo;
import com.ymttest.database.sharding.db.sharding.model.OrderDetailPo;
import com.ymttest.database.sharding.db.sharding.model.RefundBillPo;
import com.ymttest.database.sharding.db.sqlwapper.OrderShardingWapper;
import com.ymttest.utils.EnvSetup;

/**
 * 申请退货退款接口 FreeMaker Template自动生成代码
 */
@TestSuite
public class Ts_ApplySalesRefund {

	private static ApplyRefundReq applyRefundReq;
	private static ApplySalesRefundCall applySalesRefundCall;
	private static OrderShardingWapper orderShardingWapper = new OrderShardingWapper();
	
	private static long userId = 20238699;

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("申请退货退款接口-客服");
	}

	@Before
	public void caseUp() {

		applyRefundReq = new ApplyRefundReq();
		applySalesRefundCall = new ApplySalesRefundCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(applySalesRefundCall.getOpurl());
		orderShardingWapper.activeDeadCommunicationsLink(orderShardingWapper);
	}

	@After
	public void caseDown() {
		Logger.end();
	}

	/**
	 * 1个买手,2个商品，第二件商品包邮
	 * @param isUserCoupon 是否使用优惠券（同时使用平台券，商家券）
	 * @return
	 */
	public static TradingServiceResp placeOrder3() {

		Long sellerId = Long.valueOf(EnvSetup.getData("autotest_seller1"));
		String sellerName = String.valueOf(EnvSetup.getData("autotest_sellerName1"));
		
		PlaceOrderReq placeOrderReq = TradingCallService
				.buildStandPlaceOrderReq();
		
		OrderGroupVo orderGroupVo = TradingCallService.createOrderGroupVo(sellerId, sellerName);
		OrderVo orderVo = TradingCallService.createOrderVo();
		
		// 创建一个普通商品
		TradingProductVo product = TradingProductVo.createPro(sellerId,
				sellerName, 100);
		TradingProductVo productVo1 = TradingProductVo.createPro(sellerId,
				sellerName, 10);
		
		OrderItemVo orderItemVo = TradingCallService.createOrderItemVo(
				product.getProductId(), product.getCatalogId());
		OrderItemVo orderItemVo1 = TradingCallService.createOrderItemVo(
				productVo1.getProductId(), productVo1.getCatalogId());
		
		// 包邮
		orderItemVo1.setFreight(BigDecimal.ZERO);
		
		orderVo.setOrderItems(Arrays.asList(orderItemVo, orderItemVo1));
		orderGroupVo.setOrders(Arrays.asList(orderVo));
		placeOrderReq.setOrderGroups(Arrays.asList(orderGroupVo));	

		return TradingCallService.callPlaceOrderService(placeOrderReq);

	}

	//商品申请退款的上限值为：当个商品最大可退款金额+订单总运费

	// 计算订单总价格 商品价格 X 数量+运费
	/*	BigDecimal refoundAmout = orderDetailPo.getProductPrice()
				.multiply(new BigDecimal(productNum))
				.subtract(orderDetailPo.getYmtCouponAmount())
				.subtract(orderDetailPo.getSellerCouponAmount());

		//单件商品可退金额
		BigDecimal oneProRefund = refoundAmout.divide(new BigDecimal(
				productNum),2,BigDecimal.ROUND_DOWN);*/
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_001() {
		Logger.start(true, "退商品及商品运费,申请退货退款成功");
		try {

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(true, BigDecimal.ZERO,
							userId, LogisticsTypeEnum.OVERSEAS_DELIVERY);

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			long orderId = order.getOrderId();

			//第一个订单下的商品列表
			List<OrderDetailPo> orderDetailPoList = order
					.getOrderDetailPoList();
			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 付款			
			TradingCallService.payOrder(userId, amount, tradingId);

			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			// 非贝海发货
			TradingCallService.delivery(sellerId, orderId, false);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细
			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();

			for (int i = 0; i < orderDetailPoList.size(); i++) {

				OrderDetailPo orderDetailPo = orderDetailPoList.get(i);

				String catalogId = orderDetailPo.getCatalogId();

				int productNum = orderDetailPo.getProductCount();

				SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

				// 计算订单总价格 商品价格 X 数量+运费
				BigDecimal refoundAmout = (orderDetailPo.getProductPrice())
						.multiply(new BigDecimal(productNum))
						.subtract(orderDetailPo.getSellerCouponAmount())
						.subtract(orderDetailPo.getYmtCouponAmount())
						.add(orderDetailPo.getFreight());

				salesRefundInfo.setCatalogId(catalogId);

				salesRefundInfo.setRefundAmount(refoundAmout);
				salesRefundInfo.setRefundBillNo("TH" + i + orderId);
				salesRefundInfo.setRefundProductNum(orderDetailPo
						.getProductCount());

				salesRefundInfoList.add(salesRefundInfo);
			}

			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();

			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");

			int i = 0;

			if (applySalesRefundCall.getReturnData().equals("ok")) {

				// 数据库验证
				for (SalesRefundInfoVo refund : applyRefundReq
						.getSalesRefundInfoList()) {

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setProductCount(refund
							.getRefundProductNum());

					expectedRefundBillPo.setFreight(orderDetailPoList.get(i)
							.getFreight());

					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setSellerId(sellerId);
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(0);

					expectedRefundBillPo.setRefundBillStatus(1);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					i++;
				}

			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_002() {
		Logger.start(false, "申请退货退款,订单号不存在");
		try {

			applyRefundReq.setOrderId(11111);

			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();

			SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

			salesRefundInfo.setCatalogId("ssss");

			salesRefundInfo.setRefundAmount(new BigDecimal(100));
			salesRefundInfo.setRefundBillNo("YMTTF" + 11111);
			salesRefundInfo.setRefundProductNum(1);

			salesRefundInfoList.add(salesRefundInfo);
			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();
			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_003() {
		Logger.start(true, "发货后,申请退货退款成功");
		try {

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(true, BigDecimal.ZERO,
							userId, LogisticsTypeEnum.OVERSEAS_DELIVERY);

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			long orderId = order.getOrderId();

			//第一个订单下的商品列表
			List<OrderDetailPo> orderDetailPoList = order
					.getOrderDetailPoList();
			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 付款			
			TradingCallService.payOrder(userId, amount, tradingId);

			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细
			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();

			for (int i = 0; i < orderDetailPoList.size(); i++) {

				OrderDetailPo orderDetailPo = orderDetailPoList.get(i);

				String catalogId = orderDetailPo.getCatalogId();

				int productNum = orderDetailPo.getProductCount();

				SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

				// 计算订单总价格 商品价格 X 数量+运费
				BigDecimal refoundAmout = (orderDetailPo.getProductPrice())
						.multiply(new BigDecimal(productNum))
						.subtract(orderDetailPo.getSellerCouponAmount())
						.subtract(orderDetailPo.getYmtCouponAmount());

				salesRefundInfo.setCatalogId(catalogId);

				salesRefundInfo.setRefundAmount(refoundAmout);
				salesRefundInfo.setRefundBillNo("TH" + i + orderId);
				salesRefundInfo.setRefundProductNum(orderDetailPo
						.getProductCount());

				salesRefundInfoList.add(salesRefundInfo);
			}

			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();

			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");

			if (applySalesRefundCall.getReturnData().equals("ok")) {

				// 数据库验证
				for (SalesRefundInfoVo refund : applyRefundReq
						.getSalesRefundInfoList()) {

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setProductCount(refund
							.getRefundProductNum());
					expectedRefundBillPo.setFreight(BigDecimal.ZERO);
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setSellerId(sellerId);
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(0);

					expectedRefundBillPo.setRefundBillStatus(1);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

				}

			}

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_004() {
		Logger.start(true, "发货后,部分退款");
		try {

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(true, BigDecimal.ZERO,
							userId, LogisticsTypeEnum.OVERSEAS_DELIVERY);

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			long orderId = order.getOrderId();

			//第一个订单下的商品列表
			List<OrderDetailPo> orderDetailPoList = order
					.getOrderDetailPoList();
			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 付款			
			TradingCallService.payOrder(userId, amount, tradingId);

			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细
			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();

			for (int i = 0; i < orderDetailPoList.size(); i++) {

				OrderDetailPo orderDetailPo = orderDetailPoList.get(i);

				String catalogId = orderDetailPo.getCatalogId();

				int productNum = orderDetailPo.getProductCount();

				SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

				// 计算订单总价格 商品价格 X 数量+运费
				BigDecimal refoundAmout = (orderDetailPo.getProductPrice())
						.multiply(new BigDecimal(productNum))
						.subtract(orderDetailPo.getSellerCouponAmount())
						.subtract(orderDetailPo.getYmtCouponAmount());

				salesRefundInfo.setCatalogId(catalogId);

				salesRefundInfo.setRefundAmount(refoundAmout);
				salesRefundInfo.setRefundBillNo("TH" + i + orderId);
				salesRefundInfo.setRefundProductNum(orderDetailPo
						.getProductCount());

				salesRefundInfoList.add(salesRefundInfo);
			}

			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();

			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");

			if (applySalesRefundCall.getReturnData().equals("ok")) {

				// 数据库验证
				for (SalesRefundInfoVo refund : applyRefundReq
						.getSalesRefundInfoList()) {

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setProductCount(refund
							.getRefundProductNum());
					expectedRefundBillPo.setFreight(BigDecimal.ZERO);
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setSellerId(sellerId);
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(0);

					expectedRefundBillPo.setRefundBillStatus(1);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_005() {
		Logger.start(true, "同一退款单,重复申请退款");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.orderApplyRefund();

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = order.getOrderId();

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细
			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();

			for (int i = 0; i < placeOrderResp.getOrderList().get(0)
					.getOrderDetailPoList().size(); i++) {

				OrderDetailPo orderDetailPo = placeOrderResp.getOrderList()
						.get(i).getOrderDetailPoList().get(i);

				String catalogId = orderDetailPo.getCatalogId();

				int productNum = orderDetailPo.getProductCount();

				SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

				// 计算订单总价格 商品价格 X 数量+运费
				BigDecimal refoundAmout = (orderDetailPo.getProductPrice())
						.multiply(new BigDecimal(productNum))
						.subtract(orderDetailPo.getSellerCouponAmount())
						.subtract(orderDetailPo.getYmtCouponAmount());

				salesRefundInfo.setCatalogId(catalogId);

				salesRefundInfo.setRefundAmount(refoundAmout);
				salesRefundInfo.setRefundBillNo("TH" + i + orderId);
				salesRefundInfo.setRefundProductNum(orderDetailPo
						.getProductCount());

				salesRefundInfoList.add(salesRefundInfo);
			}

			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();

			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_007() {
		Logger.start(true, "商品申请退款金额大于(商品可退金额+订单总运费)");

		try {
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false, BigDecimal.ZERO,
							userId, LogisticsTypeEnum.OVERSEAS_DELIVERY);

			Order order = placeOrderResp.getOrderList().get(0);
			long orderId = order.getOrderId();

			//第一个订单下的商品列表
			BigDecimal orderFreight = order.getOrderFreight();

			applyRefundReq.setOrderId(orderId);
			// 订单商品明细

			OrderDetailPo orderDetailPo = order.getOrderDetailPoList().get(0);

			String catalogId = orderDetailPo.getCatalogId();

			int productNum = orderDetailPo.getProductCount();

			// 计算订单总价格 商品价格 X 数量+运费
			BigDecimal refoundAmout = orderDetailPo.getProductPrice()
					.multiply(new BigDecimal(productNum)).add(orderFreight)
					.add(BigDecimal.ONE);

			SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

			salesRefundInfo.setCatalogId(catalogId);
			salesRefundInfo.setRefundAmount(refoundAmout);
			salesRefundInfo.setRefundBillNo("TH" + 0 + orderId);
			salesRefundInfo.setRefundProductNum(productNum);

			applyRefundReq.setSalesRefundInfoList(Lists
					.newArrayList(salesRefundInfo));

			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();
			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");

			if (applySalesRefundCall.getReturnData().equals("ok")) {
				// 数据库验证

				for (SalesRefundInfoVo refund : applyRefundReq
						.getSalesRefundInfoList()) {

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo res = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					Logger.verifyEquals(null, res, "退款业务表（refund_bill）记录数为0");

				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_008() {
		Logger.start(true, "订单商品不是包邮,商品申请退款,只退商品,不退运费");
		try {
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false, BigDecimal.ZERO,
							userId, LogisticsTypeEnum.OVERSEAS_DELIVERY);

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			long orderId = order.getOrderId();

			//第一个订单下的商品列表			
			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 付款
			TradingCallService.payOrder(userId, amount, tradingId);
			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细

			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();

			for (int i = 0; i < order.getOrderDetailPoList().size(); i++) {

				OrderDetailPo orderDetailPo = order.getOrderDetailPoList().get(
						i);

				String catalogId = orderDetailPo.getCatalogId();

				int productNum = orderDetailPo.getProductCount();

				// 计算订单总价格 商品价格 X 数量+运费
				BigDecimal refoundAmout = orderDetailPo.getProductPrice()
						.multiply(new BigDecimal(productNum))
						.subtract(orderDetailPo.getYmtCouponAmount())
						.subtract(orderDetailPo.getSellerCouponAmount());

				SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

				salesRefundInfo.setCatalogId(catalogId);
				salesRefundInfo.setRefundAmount(refoundAmout);
				salesRefundInfo.setRefundBillNo("TH" + i + orderId);
				salesRefundInfo.setRefundProductNum(productNum);
				salesRefundInfoList.add(salesRefundInfo);

			}
			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();
			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");

			if (applySalesRefundCall.getReturnData().equals("ok")) {
				// 数据库验证
				int i = 0;

				for (SalesRefundInfoVo refund : applyRefundReq
						.getSalesRefundInfoList()) {

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setProductCount(refund
							.getRefundProductNum());

					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setSellerId(sellerId);
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(0);

					expectedRefundBillPo.setRefundBillStatus(1);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					i = i + 1;
				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_009() {
		Logger.start(true, "订单商品不是包邮,商品申请退款,商品部分退款");
		try {
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false, BigDecimal.ZERO,
							userId, LogisticsTypeEnum.OVERSEAS_DELIVERY);

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			long orderId = order.getOrderId();

			//第一个订单下的商品列表			
			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 付款
			TradingCallService.payOrder(userId, amount, tradingId);
			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细

			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();

			for (int i = 0; i < order.getOrderDetailPoList().size(); i++) {

				OrderDetailPo orderDetailPo = order.getOrderDetailPoList().get(
						i);

				String catalogId = orderDetailPo.getCatalogId();

				int productNum = orderDetailPo.getProductCount();

				// 计算订单总价格 商品价格 X 数量+运费
				BigDecimal refoundAmout = orderDetailPo.getProductPrice()
						.multiply(new BigDecimal(productNum))
						.subtract(orderDetailPo.getYmtCouponAmount())
						.subtract(orderDetailPo.getSellerCouponAmount())
						.subtract(new BigDecimal(30));

				SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

				salesRefundInfo.setCatalogId(catalogId);
				salesRefundInfo.setRefundAmount(refoundAmout);
				salesRefundInfo.setRefundBillNo("TH" + i + orderId);
				salesRefundInfo.setRefundProductNum(productNum);
				salesRefundInfoList.add(salesRefundInfo);

			}
			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();
			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");

			if (applySalesRefundCall.getReturnData().equals("ok")) {
				// 数据库验证
				int i = 0;

				for (SalesRefundInfoVo refund : applyRefundReq
						.getSalesRefundInfoList()) {

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setProductCount(refund
							.getRefundProductNum());

					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setSellerId(sellerId);
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(0);

					expectedRefundBillPo.setRefundBillStatus(1);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					i = i + 1;
				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_010() {
		Logger.start(true, "订单商品不是包邮,商品申请退款,商品全退,退部分商品运费");

		try {
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false, BigDecimal.ZERO,
							userId, LogisticsTypeEnum.OVERSEAS_DELIVERY);

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			long orderId = order.getOrderId();

			//第一个订单下的商品列表			
			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 付款
			TradingCallService.payOrder(userId, amount, tradingId);
			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细

			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();

			for (int i = 0; i < order.getOrderDetailPoList().size(); i++) {

				OrderDetailPo orderDetailPo = order.getOrderDetailPoList().get(
						i);

				String catalogId = orderDetailPo.getCatalogId();

				int productNum = orderDetailPo.getProductCount();

				// 计算订单总价格 商品价格 X 数量+运费
				BigDecimal refoundAmout = orderDetailPo.getProductPrice()
						.multiply(new BigDecimal(productNum))
						.subtract(orderDetailPo.getYmtCouponAmount())
						.subtract(orderDetailPo.getSellerCouponAmount())
						.add(new BigDecimal(2));

				SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

				salesRefundInfo.setCatalogId(catalogId);
				salesRefundInfo.setRefundAmount(refoundAmout);
				salesRefundInfo.setRefundBillNo("TH" + i + orderId);
				salesRefundInfo.setRefundProductNum(productNum);
				salesRefundInfoList.add(salesRefundInfo);

			}
			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();
			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");

			if (applySalesRefundCall.getReturnData().equals("ok")) {
				// 数据库验证
				int i = 0;

				for (SalesRefundInfoVo refund : applyRefundReq
						.getSalesRefundInfoList()) {

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setProductCount(refund
							.getRefundProductNum());
					expectedRefundBillPo.setFreight(new BigDecimal(2));
					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setSellerId(sellerId);
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(0);

					expectedRefundBillPo.setRefundBillStatus(1);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					i = i + 1;
				}
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_011() {
		Logger.start(true, "订单商品不是包邮,同意商品多次申请退款,第一次商品全额退款,商品运费还未退完,第二次申请退部分运费");
		try {
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false, BigDecimal.ZERO,
							userId, LogisticsTypeEnum.OVERSEAS_DELIVERY);

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			long orderId = order.getOrderId();

			//第一个订单下的商品列表			
			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 付款
			TradingCallService.payOrder(userId, amount, tradingId);
			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细

			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();

			// 第一个商品
			OrderDetailPo orderDetailPo = order.getOrderDetailPoList().get(0);

			String catalogId = orderDetailPo.getCatalogId();

			int productNum = orderDetailPo.getProductCount();

			BigDecimal productFreight = orderDetailPo.getFreight();

			BigDecimal refundProductFreight = productFreight
					.subtract(new BigDecimal(2));

			// 计算订单总价格 商品价格 X 数量
			BigDecimal refoundAmout = orderDetailPo.getProductPrice()
					.multiply(new BigDecimal(productNum))
					.subtract(orderDetailPo.getYmtCouponAmount())
					.subtract(orderDetailPo.getSellerCouponAmount());

			SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

			salesRefundInfo.setCatalogId(catalogId);
			salesRefundInfo.setRefundAmount(refoundAmout);
			salesRefundInfo.setRefundBillNo("TH" + 0 + orderId);
			salesRefundInfo.setRefundProductNum(productNum);

			salesRefundInfoList.add(salesRefundInfo);

			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);

			//商品第一次申请退款	
			RefundService.applyRefundCall(applyRefundReq);

			Thread.sleep(10000);

			//商品第二次申请退款			
			salesRefundInfo.setRefundAmount(refundProductFreight);
			salesRefundInfo.setRefundBillNo("TH" + 1 + orderId);

			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();

			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");

			if (applySalesRefundCall.getReturnData().equals("ok")) {
				// 数据库验证

				String refundBillNo = salesRefundInfo.getRefundBillNo();

				RefundBillPo expectedRefundBillPo = new RefundBillPo();

				expectedRefundBillPo.setRefundBillNo(refundBillNo);
				expectedRefundBillPo.setCatalogId(salesRefundInfo
						.getCatalogId());
				expectedRefundBillPo.setTotalAmount(salesRefundInfo
						.getRefundAmount());
				expectedRefundBillPo.setProductCount(salesRefundInfo
						.getRefundProductNum());

				expectedRefundBillPo.setOrderId(orderId);
				expectedRefundBillPo.setUserId(userId);
				expectedRefundBillPo.setSellerId(sellerId);
				expectedRefundBillPo.setTopspeedRefund(false);
				expectedRefundBillPo.setAfterReceiving(false);
				expectedRefundBillPo.setRefundStatus(0);

				expectedRefundBillPo.setRefundBillStatus(1);

				RefundBillPo actualRefundBillPo = orderShardingWapper
						.selectRefundBillByBillNo(refundBillNo);

				RefundService.verifyRefundBillDb(expectedRefundBillPo,
						actualRefundBillPo);

			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_012() {
		Logger.start(true, "订单里有包邮非包邮混合商品,包邮商品全退+退部分运费");
		try {
			TradingServiceResp placeOrderResp = placeOrder3();

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();
			long orderId = order.getOrderId();
			BigDecimal amount = placeOrderResp.getPayableAmount();

			//第一个订单下的商品列表

			// 付款
			TradingCallService.payOrder(userId, amount, tradingId);
			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细

			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();

			OrderDetailPo orderDetailPo = order.getOrderDetailPoList().get(1);

			String catalogId = orderDetailPo.getCatalogId();

			int productNum = orderDetailPo.getProductCount();

			// 计算订单总价格 商品价格 X 数量+运费
			BigDecimal refoundAmout = orderDetailPo.getProductPrice()
					.multiply(new BigDecimal(productNum))
					.subtract(orderDetailPo.getYmtCouponAmount())
					.subtract(orderDetailPo.getSellerCouponAmount())
					.add(BigDecimal.ONE);

			SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

			salesRefundInfo.setCatalogId(catalogId);
			salesRefundInfo.setRefundAmount(refoundAmout);
			salesRefundInfo.setRefundBillNo("TH" + 0 + orderId);
			salesRefundInfo.setRefundProductNum(productNum);

			salesRefundInfoList.add(salesRefundInfo);

			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();

			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");

			if (applySalesRefundCall.getReturnData().equals("ok")) {
				// 数据库验证
				String refundBillNo = salesRefundInfo.getRefundBillNo();

				RefundBillPo actualRefundBillPo = orderShardingWapper
						.selectRefundBillByBillNo(refundBillNo);

				Logger.verifyEquals(null, actualRefundBillPo,
						"退款业务表（refund_bill）记录数为0");
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_013() {
		Logger.start(false, "购买海淘达人会员订单，申请退货退款失败");
		try {

			applyRefundReq.setOrderId(7327278699L);

			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();

			SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

			salesRefundInfo.setCatalogId("c4255536");

			salesRefundInfo.setRefundAmount(new BigDecimal(100));
			salesRefundInfo.setRefundBillNo("YMTTF" + 11111);
			salesRefundInfo.setRefundProductNum(1);

			salesRefundInfoList.add(salesRefundInfo);
			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();
			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_014() {
		Logger.start(true, "买家承担鉴定费和鉴定物流费，全部退货退款，申请金额=商品金额+运费+买家鉴定费+买家鉴定运费,申请退货退款成功");
		try {

			TradingServiceResp placeOrder = TradingPlaceAuthenticateCallService
					.placeOrderWithAuthenticate(
							AuthenticateFreightTypeEnum.BUYER, BigDecimal.ONE,
							AuthenticateFeeTypeEnum.BUYER, BigDecimal.TEN);
			Long userId = placeOrder.getUserId();

			Order order = placeOrder.getOrderList().get(0);
			List<OrderDetailPo> orderDetailPoList = order.getOrderDetailPoList();

			long orderId = order.getOrderId();
			long sellerId = order.getSellerId();

			TradingCallService.payOrder(userId, placeOrder.getPayableAmount(),
					placeOrder.getMainOrderId());

			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细
			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();
			
			BigDecimal userAuthenticateFee = BigDecimal.ZERO;

			for (int i = 0; i < orderDetailPoList.size(); i++) {

				OrderDetailPo orderDetailPo = orderDetailPoList.get(i);
				
				String catalogId = orderDetailPo.getCatalogId();
				int refundProductNum = orderDetailPo.getProductCount();
				
				userAuthenticateFee = RefundService.getUserAuthenticateFee(
						orderDetailPo, refundProductNum).add(
						order.getUserAuthenticateFreightFee());

				SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

				BigDecimal refoundAmout = (orderDetailPo.getProductPrice())
						.multiply(new BigDecimal(refundProductNum))
						.subtract(orderDetailPo.getSellerCouponAmount())
						.subtract(orderDetailPo.getYmtCouponAmount())
						.subtract(orderDetailPo.getYmtPromotionAmount())
						.subtract(
								Utils.zeroIfNull(orderDetailPo
										.getThirdpartyDiscount()))
						.add(orderDetailPo.getFreight())
						.add(userAuthenticateFee);

				salesRefundInfo.setCatalogId(catalogId);

				salesRefundInfo.setRefundAmount(refoundAmout);
				salesRefundInfo.setRefundBillNo("TH" + i + orderId);
				salesRefundInfo.setRefundProductNum(orderDetailPo
						.getProductCount());

				salesRefundInfoList.add(salesRefundInfo);
			}

			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();

			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");
			
			int i = 0;

			if (applySalesRefundCall.getReturnData().equals("ok")) {

				// 数据库验证
				for (SalesRefundInfoVo refund : applyRefundReq
						.getSalesRefundInfoList()) {

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setProductCount(refund
							.getRefundProductNum());

					expectedRefundBillPo.setFreight(orderDetailPoList.get(i)
							.getFreight());

					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setSellerId(sellerId);
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(0);

					expectedRefundBillPo.setRefundBillStatus(1);
					
					expectedRefundBillPo.setUserAuthenticateFee(userAuthenticateFee);
					expectedRefundBillPo.setRefundType(null);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					i++;
				}
			}

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_015() {
		Logger.start(true, "买家承担鉴定费和鉴定物流费，部分退货退款，申请金额>买家鉴定费,申请退货退款成功");
		try {

			TradingServiceResp placeOrder = TradingPlaceAuthenticateCallService
					.placeOrderWithAuthenticate(
							AuthenticateFreightTypeEnum.BUYER, BigDecimal.ONE,
							AuthenticateFeeTypeEnum.BUYER, BigDecimal.TEN);
			Long userId = placeOrder.getUserId();

			Order order = placeOrder.getOrderList().get(0);
			List<OrderDetailPo> orderDetailPoList = order.getOrderDetailPoList();

			long orderId = order.getOrderId();
			long sellerId = order.getSellerId();

			TradingCallService.payOrder(userId, placeOrder.getPayableAmount(),
					placeOrder.getMainOrderId());

			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细
			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();
			
			BigDecimal userAuthenticateFee = BigDecimal.ZERO;

			for (int i = 0; i < orderDetailPoList.size(); i++) {

				OrderDetailPo orderDetailPo = orderDetailPoList.get(i);
				
				String catalogId = orderDetailPo.getCatalogId();
				int refundProductNum = 1;
				
				userAuthenticateFee = RefundService.getUserAuthenticateFee(
						orderDetailPo, refundProductNum);

				SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

				BigDecimal refoundAmout = userAuthenticateFee;

				salesRefundInfo.setCatalogId(catalogId);

				salesRefundInfo.setRefundAmount(refoundAmout.add(BigDecimal.ONE));
				salesRefundInfo.setRefundBillNo("TH" + i + orderId);
				salesRefundInfo.setRefundProductNum(refundProductNum);

				salesRefundInfoList.add(salesRefundInfo);
			}

			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();

			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");
			
			int i = 0;

			if (applySalesRefundCall.getReturnData().equals("ok")) {

				// 数据库验证
				for (SalesRefundInfoVo refund : applyRefundReq
						.getSalesRefundInfoList()) {

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setProductCount(refund
							.getRefundProductNum());

					expectedRefundBillPo.setFreight(BigDecimal.ZERO);

					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setSellerId(sellerId);
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(0);

					expectedRefundBillPo.setRefundBillStatus(1);
					
					expectedRefundBillPo.setUserAuthenticateFee(userAuthenticateFee);
					expectedRefundBillPo.setRefundType(null);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					i = i + 1;
				}
			}

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({P1.class})
	@TestCase
	@Ignore
	// 客服后台不会有这个情况
	public void Tc_ApplySalesRefund_016() {
		Logger.start(true, "买家承担鉴定费和鉴定物流费，商品一个一个退全款，申请退货退款成功");
		try {

			TradingServiceResp placeOrder = TradingPlaceAuthenticateCallService
					.placeOrderWithAuthenticate(
							AuthenticateFreightTypeEnum.BUYER, BigDecimal.ONE,
							AuthenticateFeeTypeEnum.BUYER, BigDecimal.TEN);
			Long userId = placeOrder.getUserId();

			Order order = placeOrder.getOrderList().get(0);
			List<OrderDetailPo> orderDetailPoList = order.getOrderDetailPoList();

			long orderId = order.getOrderId();
			long sellerId = order.getSellerId();

			TradingCallService.payOrder(userId, placeOrder.getPayableAmount(),
					placeOrder.getMainOrderId());

			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细
			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();
			
			BigDecimal userAuthenticateFee = BigDecimal.ZERO;
			OrderDetailPo orderDetailPo = orderDetailPoList.get(0);

			for (int i = 0; i < orderDetailPo.getProductCount(); i++) {
				
				String catalogId = orderDetailPo.getCatalogId();
				int refundProductNum = 1;
				
				userAuthenticateFee = RefundService.getUserAuthenticateFee(
						orderDetailPo, refundProductNum);
				
				if (i == orderDetailPo.getProductCount() - 1)
					userAuthenticateFee.add(order.getUserAuthenticateFreightFee());

				SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

				BigDecimal refoundAmout = orderDetailPo.getProductPrice()
						.multiply(new BigDecimal(refundProductNum))
						.subtract(orderDetailPo.getSellerCouponAmount())
						.subtract(orderDetailPo.getYmtCouponAmount())
						.subtract(orderDetailPo.getYmtPromotionAmount())
						.subtract(
								Utils.zeroIfNull(orderDetailPo
										.getThirdpartyDiscount()))
						.add(orderDetailPo.getFreight())
						.add(userAuthenticateFee);

				salesRefundInfo.setCatalogId(catalogId);

				salesRefundInfo.setRefundAmount(refoundAmout);
				salesRefundInfo.setRefundBillNo("TH" + i + orderId);
				salesRefundInfo.setRefundProductNum(refundProductNum);

				salesRefundInfoList.add(salesRefundInfo);
			}

			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();

			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");
			
			int i = 0;

			if (applySalesRefundCall.getReturnData().equals("ok")) {

				// 数据库验证
				for (SalesRefundInfoVo refund : applyRefundReq
						.getSalesRefundInfoList()) {

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setProductCount(refund
							.getRefundProductNum());

					expectedRefundBillPo.setFreight(orderDetailPoList.get(i)
							.getFreight());

					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setSellerId(sellerId);
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(0);

					expectedRefundBillPo.setRefundBillStatus(1);
					
					expectedRefundBillPo.setUserAuthenticateFee(userAuthenticateFee);
					expectedRefundBillPo.setRefundType(null);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					i++;
				}
			}

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_017() {
		Logger.start(true, "订单包含普通商品、买手鉴定费商品、买家鉴定费商品，全部退货退款，申请退货退款成功");
		try {

			// 创建订单
			Logger.comment("前置数据准备");

			Long sellerId = Long.valueOf(EnvSetup.getData("autotest_seller1"));
			String sellername = EnvSetup.getData("autotest_sellerName1");

			PlaceOrderReq placeOrderReq = TradingCallService
					.buildStandPlaceOrderReq();
			
			Long userId = placeOrderReq.getUserId();
			
			OrderGroupVo orderGroupVo = TradingCallService.createOrderGroupVo(sellerId, sellername);
			OrderVo orderVo = TradingCallService.createOrderVo();
			
			orderVo.withAuthenticateFreight(BigDecimal.ONE)
					.withAuthenticateFreightType(
							AuthenticateFreightTypeEnum.SELLER.getCode());
			
			// 创建一个普通商品
			TradingProductVo product = TradingProductVo.createPro(sellerId,
					sellername, 100);
			
			OrderItemVo orderItemVo = TradingCallService.createOrderItemVo(
					product.getProductId(), product.getCatalogId());
			
			// 第二个商品，买家鉴别费
			TradingProductVo pro = TradingProductVo.createPro(sellerId,
					sellername, 100);

			OrderItemVo orderItemVo_order1_2 = TradingCallService
					.createOrderItemVo(pro.getProductId(), pro.getCatalogId());

			orderItemVo_order1_2
					.withAuthenticateFlag(true)
					.withAuthenticateFee(BigDecimal.TEN)
					.withAuthenticateFeeType(
							AuthenticateFeeTypeEnum.BUYER.getCode());

			// 第三个商品，买手鉴别费
			pro = TradingProductVo.createPro(sellerId, sellername, 100);

			OrderItemVo orderItemVo_order1_3 = TradingCallService
					.createOrderItemVo(pro.getProductId(), pro.getCatalogId());

			orderItemVo_order1_3
					.withAuthenticateFlag(true)
					.withAuthenticateFee(BigDecimal.TEN)
					.withAuthenticateFeeType(
							AuthenticateFeeTypeEnum.SELLER.getCode());

			orderVo.setOrderItems(Arrays.asList(orderItemVo, orderItemVo_order1_2, orderItemVo_order1_3));
			orderGroupVo.setOrders(Arrays.asList(orderVo));
			placeOrderReq.setOrderGroups(Arrays.asList(orderGroupVo));			

			TradingServiceResp placeOrder = TradingCallService
					.callPlaceOrderService(placeOrderReq);

			TradingCallService.payOrder(userId, placeOrder.getPayableAmount(),
					placeOrder.getMainOrderId());

			Order order = placeOrder.getOrderList().get(0);
			Long orderId = order.getOrderId();
			
			List<OrderDetailPo> orderDetailPoList = order.getOrderDetailPoList();

			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细
			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();
			
			BigDecimal userAuthenticateFee = BigDecimal.ZERO;

			for (int i = 0; i < orderDetailPoList.size(); i++) {

				OrderDetailPo orderDetailPo = orderDetailPoList.get(i);
				
				String catalogId = orderDetailPo.getCatalogId();
				int refundProductNum = orderDetailPo.getProductCount();
				
				userAuthenticateFee = RefundService.getUserAuthenticateFee(
						orderDetailPo, refundProductNum).add(
						order.getUserAuthenticateFreightFee());

				SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

				BigDecimal refoundAmout = (orderDetailPo.getProductPrice())
						.multiply(new BigDecimal(refundProductNum))
						.subtract(orderDetailPo.getSellerCouponAmount())
						.subtract(orderDetailPo.getYmtCouponAmount())
						.subtract(orderDetailPo.getYmtPromotionAmount())
						.subtract(
								Utils.zeroIfNull(orderDetailPo
										.getThirdpartyDiscount()))
						.add(orderDetailPo.getFreight())
						.add(userAuthenticateFee);

				salesRefundInfo.setCatalogId(catalogId);

				salesRefundInfo.setRefundAmount(refoundAmout);
				salesRefundInfo.setRefundBillNo("TH" + i + orderId);
				salesRefundInfo.setRefundProductNum(orderDetailPo
						.getProductCount());
				salesRefundInfo.setUserAuthenticateFee(userAuthenticateFee);

				salesRefundInfoList.add(salesRefundInfo);
			}

			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();

			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");
			
			int i = 0;

			if (applySalesRefundCall.getReturnData().equals("ok")) {

				// 数据库验证
				for (SalesRefundInfoVo refund : applyRefundReq
						.getSalesRefundInfoList()) {

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setProductCount(refund
							.getRefundProductNum());

					expectedRefundBillPo.setFreight(orderDetailPoList.get(i)
							.getFreight());

					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setSellerId(sellerId);
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(0);

					expectedRefundBillPo.setRefundBillStatus(1);
					
					expectedRefundBillPo.setUserAuthenticateFee(refund.getUserAuthenticateFee());
					expectedRefundBillPo.setRefundType(null);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					i++;
				}
			}

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_018() {
		Logger.start(true, "订单包含普通商品、买家鉴定费商品，买家鉴定费商品全部退货退款，申请退货退款成功");
		try {

			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrder = TradingPlaceAuthenticateCallService
					.placeOrderWithAuthenticateWithTwoTypeProduct(
							AuthenticateFreightTypeEnum.BUYER, BigDecimal.ONE,
							AuthenticateFeeTypeEnum.BUYER, BigDecimal.TEN);
			
			Long userId = placeOrder.getUserId();

			TradingCallService.payOrder(userId, placeOrder.getPayableAmount(),
					placeOrder.getMainOrderId());

			Order order = placeOrder.getOrderList().get(0);
			Long orderId = order.getOrderId();
			Long sellerId = order.getSellerId();

			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细
			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();
			
			BigDecimal userAuthenticateFee = BigDecimal.ZERO;

			OrderDetailPo orderDetailPo = order.getOrderDetailPoList().stream()
					.filter(od -> od.getAuthenticateFlag() == true)
					.collect(Collectors.toList()).get(0);
			
			String catalogId = orderDetailPo.getCatalogId();
			int refundProductNum = orderDetailPo.getProductCount();
			
			userAuthenticateFee = RefundService.getUserAuthenticateFee(
					orderDetailPo, refundProductNum);

			if (Utils.zeroIfNull(orderDetailPo.getAuthenticateFeeType()) == AuthenticateFeeTypeEnum.BUYER
					.getCode())
				userAuthenticateFee = userAuthenticateFee.add(order
						.getUserAuthenticateFreightFee());

			SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

			BigDecimal refoundAmout = (orderDetailPo.getProductPrice())
					.multiply(new BigDecimal(refundProductNum))
					.subtract(orderDetailPo.getSellerCouponAmount())
					.subtract(orderDetailPo.getYmtCouponAmount())
					.subtract(orderDetailPo.getYmtPromotionAmount())
					.subtract(
							Utils.zeroIfNull(orderDetailPo
									.getThirdpartyDiscount()))
					.add(orderDetailPo.getFreight())
					.add(userAuthenticateFee);

			salesRefundInfo.setCatalogId(catalogId);

			salesRefundInfo.setRefundAmount(refoundAmout);
			salesRefundInfo.setRefundBillNo("TH" + 0 + orderId);
			salesRefundInfo.setRefundProductNum(orderDetailPo
					.getProductCount());
			salesRefundInfo.setUserAuthenticateFee(userAuthenticateFee);

			salesRefundInfoList.add(salesRefundInfo);

			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();

			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");

			if (applySalesRefundCall.getReturnData().equals("ok")) {

				// 数据库验证
				for (SalesRefundInfoVo refund : applyRefundReq
						.getSalesRefundInfoList()) {

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setProductCount(refund
							.getRefundProductNum());

					expectedRefundBillPo.setFreight(orderDetailPo
							.getFreight());

					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setSellerId(sellerId);
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(0);

					expectedRefundBillPo.setRefundBillStatus(1);
					
					expectedRefundBillPo.setUserAuthenticateFee(refund.getUserAuthenticateFee());
					expectedRefundBillPo.setRefundType(null);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);
				}
			}

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_ApplySalesRefund_019() {
		Logger.start(true, "买家承担鉴定费和鉴定物流费，鉴定中心发货，全部退货退款，申请金额=商品金额+运费+买家鉴定费,申请退货退款成功");
		try {

			TradingServiceResp placeOrder = TradingPlaceAuthenticateCallService
					.placeOrderWithAuthenticate(
							AuthenticateFreightTypeEnum.BUYER, BigDecimal.ONE,
							AuthenticateFeeTypeEnum.BUYER, BigDecimal.TEN);
			Long userId = placeOrder.getUserId();

			Order order = placeOrder.getOrderList().get(0);
			List<OrderDetailPo> orderDetailPoList = order.getOrderDetailPoList();

			long orderId = order.getOrderId();
			long sellerId = order.getSellerId();

			TradingCallService.payOrder(userId, placeOrder.getPayableAmount(),
					placeOrder.getMainOrderId());

			// 卖家接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);
			Thread.sleep(3000);
			
			// 国际段发货
			TradingCallService.delivery(sellerId, orderId, LogisticsTypeEnum.OVERSEAS_DELIVERY, "Y013", 1, true);
			
			// 鉴定中心发货
			TradingCallService.authenticateDelivery(sellerId, orderId);
			Thread.sleep(3000);

			applyRefundReq.setOrderId(orderId);

			// 订单商品明细
			List<SalesRefundInfoVo> salesRefundInfoList = new ArrayList<SalesRefundInfoVo>();
			
			BigDecimal userAuthenticateFee = BigDecimal.ZERO;

			for (int i = 0; i < orderDetailPoList.size(); i++) {

				OrderDetailPo orderDetailPo = orderDetailPoList.get(i);
				
				String catalogId = orderDetailPo.getCatalogId();
				int refundProductNum = orderDetailPo.getProductCount();
				
				userAuthenticateFee = RefundService.getUserAuthenticateFee(
						orderDetailPo, refundProductNum).add(
						order.getUserAuthenticateFreightFee());

				SalesRefundInfoVo salesRefundInfo = new SalesRefundInfoVo();

				BigDecimal refoundAmout = (orderDetailPo.getProductPrice())
						.multiply(new BigDecimal(refundProductNum))
						.subtract(orderDetailPo.getSellerCouponAmount())
						.subtract(orderDetailPo.getYmtCouponAmount())
						.subtract(orderDetailPo.getYmtPromotionAmount())
						.subtract(
								Utils.zeroIfNull(orderDetailPo
										.getThirdpartyDiscount()))
						.add(orderDetailPo.getFreight())
						.add(userAuthenticateFee);

				salesRefundInfo.setCatalogId(catalogId);

				salesRefundInfo.setRefundAmount(refoundAmout);
				salesRefundInfo.setRefundBillNo("TH" + i + orderId);
				salesRefundInfo.setRefundProductNum(orderDetailPo
						.getProductCount());

				salesRefundInfoList.add(salesRefundInfo);
			}

			applyRefundReq.setSalesRefundInfoList(salesRefundInfoList);
			applySalesRefundCall.setData(applyRefundReq);
			applySalesRefundCall.callService();

			Logger.verifyEquals("ok", applySalesRefundCall.getReturnData(),
					"验证申请退货退款接口返回正常");
			
			int i = 0;

			if (applySalesRefundCall.getReturnData().equals("ok")) {

				// 数据库验证
				for (SalesRefundInfoVo refund : applyRefundReq
						.getSalesRefundInfoList()) {

					String refundBillNo = refund.getRefundBillNo();

					RefundBillPo expectedRefundBillPo = new RefundBillPo();

					expectedRefundBillPo.setRefundBillNo(refundBillNo);
					expectedRefundBillPo.setCatalogId(refund.getCatalogId());
					expectedRefundBillPo.setTotalAmount(refund
							.getRefundAmount());
					expectedRefundBillPo.setProductCount(refund
							.getRefundProductNum());

					expectedRefundBillPo.setFreight(orderDetailPoList.get(i)
							.getFreight());

					expectedRefundBillPo.setOrderId(orderId);
					expectedRefundBillPo.setUserId(userId);
					expectedRefundBillPo.setSellerId(sellerId);
					expectedRefundBillPo.setTopspeedRefund(false);
					expectedRefundBillPo.setAfterReceiving(false);
					expectedRefundBillPo.setRefundStatus(0);

					expectedRefundBillPo.setRefundBillStatus(1);
					
					expectedRefundBillPo.setUserAuthenticateFee(userAuthenticateFee);
					expectedRefundBillPo.setRefundType(null);

					RefundBillPo actualRefundBillPo = orderShardingWapper
							.selectRefundBillByBillNo(refundBillNo);

					RefundService.verifyRefundBillDb(expectedRefundBillPo,
							actualRefundBillPo);

					i++;
				}
			}

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
}
